package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractFineClueService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.PaasFormDataHelper;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.service.dynamic.help.DynamicHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.parent.interfaces.logger.OperationLogFactory;
import com.xbongbong.pro.domain.entity.ReRollBackEntity;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.pro.formdata.pojo.vo.SaveVO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.saas.domain.entity.CustomerSubDataEntity;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.help.workflow.MarketActivityForStaticHelp;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerSubDataModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.CustomerService;
import com.xbongbong.saas.service.MarketActivityForStaticService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * 客户模块新建保存逻辑的具体实现
 * @author 魏荣杰
 * @date 2020/12/30 10:23
 * @since
 * @version
 */
@Service("customerFormDataServiceImpl")
public class CustomerFormDataServiceImpl extends AbstractFineClueService {

    private static final Logger LOG = LoggerFactory.getLogger(CustomerFormDataServiceImpl.class);
    @Resource
    private CustomerModel customerModel;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private MarketActivityForStaticService marketActivityForStaticService;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private CustomerService customerService;
    @Resource
    private OperationLogFactory operationLogFactory;
    @Resource
    private DynamicHelp dynamicHelp;
    @Resource
    private ProModelService proModelService;
    @Resource
    private MarketActivityForStaticHelp marketActivityForStaticHelp;
    @Resource
    private CustomerSubDataModel customerSubDataModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private PaasFormDataHelper paasFormDataHelper;

    @Override
    public List<Integer> businessList() {
        return Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
    }

    @Override
    public SaveVO save(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        PaasFormDataEntity newPaasFormDataEntity = beforeSaveVO.getPaasFormDataEntity();
        try {
            UserVO userVO = getUserName(formDataAddDTO, newPaasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();
            if (noApprovalRequired.equals(1)) {
                JSONObject data = newPaasFormDataEntity.getData();
                //兼容审批移除上一步data放入的 ownerId, coUserId todo 可以抽成方法
                data.remove(CustomerManagementEnum.ADD_CONTACT.getAttr());
                //兼容线索转换客户的特殊逻辑（移除 data中的 clueId 和 isBringCustomer ，防止es插入报错自）
                formDataAddDTO.setIsBringCustomer(data.getInteger("isBringCustomer"));
                formDataAddDTO.setClueId(data.getLong("clueId"));
                data.remove("clueId");
                data.remove("isBringCustomer");
                FormDataUtil.removeSystemData(data);
                Object richTextData = removeRichText(data);
                newPaasFormDataEntity.setData(data);
                CustomerEntityExt customerEntityExt = new CustomerEntityExt();
                BeanUtil.copyProperties(newPaasFormDataEntity, customerEntityExt);
                customerModel.insert(customerEntityExt);
                dataId = customerEntityExt.getId();

                // 设置属性用于返回
                setPartialAttributes(dataId, customerEntityExt.getSubFormData(), customerEntityExt.getData(), customerEntityExt.getAddTime(),
                        customerEntityExt.getUpdateTime(), newPaasFormDataEntity, beforeSaveVO);

                //文件柜数据保存
                saveFile(formDataAddDTO, newPaasFormDataEntity, userVO);
                //富文本数据保存
                saveRichText(formDataAddDTO, newPaasFormDataEntity, richTextData);
            }
            return new SaveVO(noApprovalRequired, newPaasFormDataEntity, dataId, userVO);
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }

    }



    @Override
    public FormDataAddVO afterSave(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();

        PaasFormDataEntity newPaasFormDataEntity = beforeSaveVO.getPaasFormDataEntity();
        PaasFormEntityExt paasFormEntityExt = beforeSaveVO.getPaasFormEntityExt();
        Long dataId = newPaasFormDataEntity.getId();

        Integer noApprovalRequired = saveVO.getNoApprovalRequired();
        ReRollBackEntity reRollBackEntity = new ReRollBackEntity();
        try {
            if (noApprovalRequired.equals(1) ) {
                // aftersave
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = beforeSaveVO.getSaasNeedRedundantAttrPojo();
                SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
                BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);
                packageSaasFormInsertSaveDTO(saasFormSaveDTO, newPaasFormDataEntity);
                saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPoJo);
                customerService.afterSave(saasFormSaveDTO);
                // 添加市场活动
//                addMarketActivity(newPaasFormDataEntity);
                marketActivityForStaticHelp.addMarketActivity(newPaasFormDataEntity, XbbRefTypeEnum.CUSTOMER_MANAGEMENT);
                // 批量编辑/新建联系人
                paasFormDataHelper.batchEditContact(saasNeedRedundantAttrPoJo, formDataAddDTO.getLoginUser(), newPaasFormDataEntity.getCreatorId(), corpid, dataId, newPaasFormDataEntity.getData().getString(CustomerManagementEnum.NAME.getAttr()), formDataAddDTO.getIsImport(), ContactEnum.CUSTOMER_NAME.getAttr(), XbbRefTypeEnum.CONTACT);

                // log
                afterSaveLog(formDataAddDTO, paasFormEntityExt, newPaasFormDataEntity, saveVO, beforeSaveVO);
                // 动态处理
                dynamicHelp.addLinkData(saasFormSaveDTO);
                // api
                apiHook(formDataAddDTO, saveVO, beforeSaveVO);

                // 业务规则
                activeRule(formDataAddDTO, beforeSaveVO, newPaasFormDataEntity, paasFormEntityExt);

                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
                formDataAddVO.setDataId(newPaasFormDataEntity.getId());
            } else {
                formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                formDataAddVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
            }
            formDataAddVO.setFormDataId(newPaasFormDataEntity.getId());
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            afterSaveRollBack(newPaasFormDataEntity, dataId, corpid, saasMark, businessType, reRollBackEntity);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            afterSaveRollBack(newPaasFormDataEntity, dataId, corpid, saasMark, businessType, reRollBackEntity);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }

        return formDataAddVO;
    }

    @Override
    public void apiHook(FormDataAddDTO formDataAddDTO, SaveVO saveVO, BeforeSaveVO beforeSaveVO) throws XbbException {
        lowCodeExecuteService(formDataAddDTO, saveVO, beforeSaveVO);
    }

    /*private void addMarketActivity(PaasFormDataEntity newPaasFormDataEntity)  throws XbbException{
        // 市场活动
        Runnable runnable = () -> {
            try {

                marketActivityForStaticService.addMarketActivity(newPaasFormDataEntity, XbbRefTypeEnum.CUSTOMER_MANAGEMENT);
            } catch (Exception e) {
                LOG.error("统计市场活动-----"+ XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()+"数据id" +newPaasFormDataEntity.getId()+" 公司id"+newPaasFormDataEntity.getCorpid());
                LOG.error("统计市场活动- 添加数据", e);
            }
        };
        threadPoolBeanConfig.staticsMarketData().execute(runnable);
    }*/

    @Override
    public SaveVO saveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity newPaasFormDataEntity) throws XbbException {
        Long dataId = 0L;
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();
        try {
            UserVO userVO = getUserName(formDataAddDTO, newPaasFormDataEntity);
            Integer noApprovalRequired = beforeSaveVO.getNoApprovalRequired();
            JSONObject data = newPaasFormDataEntity.getData();
            Object richTextData = removeRichText(data);
            JSONObject originData = (JSONObject) data.clone();
            //兼容审批移除上一步data放入的 ownerId, coUserId todo 可以抽成方法
            data.remove(CustomerManagementEnum.ADD_CONTACT.getAttr());
            //兼容线索转换客户的特殊逻辑（移除 data中的 clueId 和 isBringCustomer ，防止es插入报错自）
            formDataAddDTO.setIsBringCustomer(data.getInteger("isBringCustomer"));
            formDataAddDTO.setClueId(data.getLong("clueId"));
            data.remove("clueId");
            data.remove("isBringCustomer");
            FormDataUtil.removeSystemData(data);
            newPaasFormDataEntity.setData(data);
            CustomerEntityExt customerEntityExt = new CustomerEntityExt();
            BeanUtil.copyProperties(newPaasFormDataEntity, customerEntityExt);
            customerModel.insert(customerEntityExt);
            dataId = customerEntityExt.getId();

            // 设置属性用于返回
            setPartialAttributes(dataId, customerEntityExt.getSubFormData(), customerEntityExt.getData(), customerEntityExt.getAddTime(), customerEntityExt.getUpdateTime(), newPaasFormDataEntity, beforeSaveVO);

            //文件柜数据保存
//            saveFile(formDataAddDTO, newPaasFormDataEntity, userVO);
            //富文本数据保存
            saveRichText(formDataAddDTO, newPaasFormDataEntity, richTextData);

            originData.put("clueId", formDataAddDTO.getClueId());
            originData.put("isBringCustomer", formDataAddDTO.getIsBringCustomer());
            newPaasFormDataEntity.setData(originData);
            return new SaveVO(noApprovalRequired, newPaasFormDataEntity, dataId, userVO);
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            saveRollBack(dataId, corpid, saasMark, businessType);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }

    }

    @Override
    public FormDataAddVO afterSaveForWorkflow(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, SaveVO saveVO, PaasFormEntityExt paasFormEntity, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        String corpid = formDataAddDTO.getCorpid();
        Integer saasMark = formDataAddDTO.getSaasMark();
        Integer businessType = formDataAddDTO.getBusinessType();

        PaasFormDataEntity newPaasFormDataEntity = beforeSaveVO.getPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getId();

        ReRollBackEntity reRollBackEntity = new ReRollBackEntity();
        try {
            // aftersave
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = beforeSaveVO.getSaasNeedRedundantAttrPojo();
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
            BeanUtil.copyProperties(formDataAddDTO, saasFormSaveDTO);
            packageSaasFormInsertSaveDTO(saasFormSaveDTO, newPaasFormDataEntity);
            saasFormSaveDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPoJo);
            customerService.afterSaveForWorkflow(saasFormSaveDTO);
            // 添加市场活动
//            addMarketActivity(newPaasFormDataEntity);
            // 批量编辑/新建联系人
//            batchEditContact(saasNeedRedundantAttrPoJo, formDataAddDTO.getLoginUser(), newPaasFormDataEntity);

            // log
//            afterSaveLog(formDataAddDTO, newPaasFormDataEntity, saveVO, beforeSaveVO);
            // api
//            apiHook(formDataAddDTO, saveVO, beforeSaveVO);

            // 业务规则
//            activeRule(formDataAddDTO, beforeSaveVO, newPaasFormDataEntity, paasFormEntityExt);

            formDataAddVO.setDataId(newPaasFormDataEntity.getId());
            formDataAddVO.setFormDataId(newPaasFormDataEntity.getId());
            formDataAddVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
            formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
        } catch (XbbException e) {
            LOG.warn(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            afterSaveRollBack(newPaasFormDataEntity, dataId, corpid, saasMark, businessType, reRollBackEntity);
            throw e;
        } catch (Exception e) {
            LOG.error(BuinessDefaultErrorCodeEnum.API_ERROR_200018.getMsg(),e);
            afterSaveRollBack(newPaasFormDataEntity, dataId, corpid, saasMark, businessType, reRollBackEntity);
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200018);
        }

        return formDataAddVO;
    }

    @Override
    public void saveRollBack(Long dataId, String corpid, Integer saasMark, Integer businessType) throws XbbException {
        try {
            IndexTypeEnum indexTypeEnum = getIndexTypeEnum(corpid, saasMark, businessType);
            //删除主表es数据
            physicalDeleteFormData(dataId, corpid, indexTypeEnum);
            // 子表单的删除
            List<CustomerSubDataEntity> bomBillSubDataEntities = customerSubDataModel.getByDataId(dataId, corpid);
            if (CollectionsUtil.isNotEmpty(bomBillSubDataEntities)) {
                IndexTypeEnum customerSubIndex = indexTypeModel.getCustomerSubIndex(corpid, businessType, saasMark);
                physicalDeleteSubBatch(corpid, bomBillSubDataEntities, customerSubIndex);
            }
        } catch (Exception e) {
            LOG.error("abstractFormDataServiceImpl.saveRollBack 回滚失败：", e);
        }

    }

    @Override
    public void afterSaveRollBack(PaasFormDataEntity newPaasFormDataEntity, Long dataId, String corpid, Integer saasMark, Integer businessType, ReRollBackEntity reRollBackEntity) throws XbbException {
        try {
            if (dataId == null || dataId == 0 || corpid == null || saasMark == null) {
                return ;
            }
            // 主业务以及子表单数据删除
            saveRollBack(dataId, corpid, saasMark, businessType);
            // 主业关联数据删除（如团队）
            // 关联新建业务数据删除
            // 关联新建业务数据子表单数据删除
        } catch (Exception e) {
            LOG.error("abstractFormDataServiceImpl.afterSaveRollBack 回滚失败：", e);
        }

    }
}
